﻿
namespace n_ModuleForm
{
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using n_MDesignPanel;
using n_UserModule;
using n_GUIcoder;
using linkboy_IDE.n_ValueForm;
using n_SimulateObj;

/// <summary>
/// Description of WorkForm.
/// </summary>
public partial class ModuleForm : Form
{
	public static ValueForm ValueBox;
	
	MDesignPanel MPanel;
	
	public bool isChanged;
	
	//当前最近打开的组件文件路径
	string CurrentModuleFilePath;
	
	//主窗口
	public ModuleForm( string MFileName )
	{
		InitializeComponent();
		
		panel1.Width = 249;
		
		this.comboBox端口功能名称.SelectedIndex = 0;
		
		this.comboBoxMasOrCli.SelectedIndex = 0;
		this.comboBox导线方向.SelectedIndex = 0;
		
		MPanel = new MDesignPanel( this.panel4.Width, this.panel4.Height );
		this.panel4.Controls.Add( MPanel );
		
		ValueBox = new ValueForm();
		
		CurrentModuleFilePath = null;
		
		isChanged = false;
		
		if( MFileName != null ) {
			try {
				LoadModule( MFileName );
			}
			catch( Exception e ) {
				MessageBox.Show( "<ModuleForm> 组件文件的格式不对:" + e );
			}
		}
		MPanel.Focus();
	}
	
	//从文件中装载组件
	public void LoadModule( string FileName )
	{
		CurrentModuleFilePath = FileName;
		
		int tLength = 0;
		int tZLength = 0;
		string BaseName = null;
		bool isControlModule = false;
		bool isClientModule = false;
		bool isClientControlPad = false;
		bool isClientChannel = false;
		bool isVHRemoModule = false;
		bool isYuanJian = false;
		Size sz = Size.Empty;
		Image BackImage = null;
		string Version = "0";
		string SimValueList = null;
		string InitDataList = null;
		string ImagePath = null;
		bool CanSwap = false;
		BasePort[] tPortList = null;
		BasePort[] tZWireList = null;
		
		string UserName = null;
		string ImageList = null;
		string DriverFilePath = null;
		string Config = null;
		string MesFilePath = null;
		string DeviceType = null;
		string EXMes = null;
		
		GUIcoder.LoadModule(
			FileName,
			ref tPortList,
			ref tZWireList,
			ref tLength,
			ref tZLength,
			ref BaseName,
			ref ImagePath,
			ref BackImage,
			ref UserName,
			ref DeviceType,
			ref ImageList,
			ref DriverFilePath,
			ref Config,
			ref MesFilePath,
			ref EXMes,
			ref sz,
			ref InitDataList,
			ref SimValueList,
			ref isControlModule,
			ref isClientModule,
			ref isClientControlPad,
		    ref isClientChannel,
		    ref isVHRemoModule,
		    ref isYuanJian,
		    ref CanSwap,
			ref Version );
		
		MPanel.myModule = new UserModule( BaseName, this.MPanel.Width/2, this.MPanel.Height/2 );
		MPanel.myModule.SetBackImage( BackImage );
		if( sz != Size.Empty ) {
			MPanel.myModule.Width = sz.Width;
			MPanel.myModule.Height = sz.Height;
		}
		
		MPanel.myModule.UserName = UserName;
		MPanel.myModule.DeviceType = DeviceType;
		MPanel.myModule.ImageList = ImageList;
		MPanel.myModule.DriverFilePath = DriverFilePath;
		MPanel.myModule.Config = Config;
		MPanel.myModule.MesFilePath = MesFilePath;
		MPanel.myModule.EXMes = EXMes;
		
		MPanel.myModule.ImagePath = ImagePath;
		MPanel.myModule.isControlModule = isControlModule;
		MPanel.myModule.isClientModule = isClientModule;
		MPanel.myModule.isClientControlPad = isClientControlPad;
		MPanel.myModule.isClientChannel = isClientChannel;
		MPanel.myModule.isVHRemoModule = isVHRemoModule;
		MPanel.myModule.isYuanJian = isYuanJian;
		MPanel.myModule.CanSwap = CanSwap;
		MPanel.myModule.Version = Version;
		
		MPanel.ClearSimList();
		MPanel.SetSimListValue( SimValueList );
		MPanel.InitDataList = InitDataList;
		
		MPanel.myPortList.ClearPortList();
		
		for( int i = 0; i < tLength; ++i ) {
			UserPort port = new UserPort(
				tPortList[ i ].Name,
				tPortList[ i ].FuncType,
				tPortList[ i ].FuncName,
				tPortList[ i ].Style,
				tPortList[ i ].SubPortConfig,
				tPortList[ i ].DirType,
				tPortList[ i ].ExtValue );
			port.X = MPanel.myModule.X + tPortList[ i ].X;
			port.Y = MPanel.myModule.Y + tPortList[ i ].Y;
			string Error = MPanel.myPortList.AddPort( port, false );
			if( Error != null ) {
				MessageBox.Show( "添加端口失败,原因: " + Error );
			}
		}
		/*
		for( int i = 0; i < tZLength; ++i ) {
			UserPort port = new UserPort(
				tZWireList[ i ].Name,
				tZWireList[ i ].FuncType,
				tZWireList[ i ].FuncName,
				tZWireList[ i ].Style,
				tZWireList[ i ].SubPortConfig,
				tZWireList[ i ].DirType,
				tZWireList[ i ].ExtValue );
			port.X = MPanel.myModule.X + tZWireList[ i ].X;
			port.Y = MPanel.myModule.Y + tZWireList[ i ].Y;
			string Error = MPanel.myZWireList.AddPort( port, false );
			if( Error != null ) {
				MessageBox.Show( "添加端口失败,原因: " + Error );
			}
		}
		*/
		RefreshMessage();
	}
	
	//显示组件的信息
	void RefreshMessage()
	{
		this.checkBox控制器组件.Checked = MPanel.myModule.isControlModule;
		//this.checkBox控件类组件.Checked = MPanel.myModule.isClientModule;
		//this.checkBox客户端控制板.Checked = MPanel.myModule.isClientControlPad;
		this.checkBox通信通道.Checked = MPanel.myModule.isClientChannel;
		this.checkBoxRemo.Checked = MPanel.myModule.isVHRemoModule;
		this.checkBoxYuanJian.Checked = MPanel.myModule.isYuanJian;
		this.checkBoxCanSwap.Checked = MPanel.myModule.CanSwap;
		this.textBoxScale.Text = (MPanel.myModule.Width - MPanel.myModule.ModuleBackImage.Width).ToString();
		
		组件名称textBox.Text = MPanel.myModule.Name;
		textBoxType.Text = MPanel.myModule.DeviceType;
		textBoxImgPath.Text = MPanel.myModule.ImagePath;
		
		textBoxDriverPath.Text = MPanel.myModule.DriverFilePath;
		textBoxImageList.Text = MPanel.myModule.ImageList;
		textBoxUserName.Text = MPanel.myModule.UserName;
		
		textBoxEX.Text = MPanel.myModule.EXMes;
		
		if( MPanel.myModule.Config != null ) {
			textBoxConfig.Text = MPanel.myModule.Config.Replace( '`', '\n' );
		}
		if( MPanel.myModule.MesFilePath != null ) {
			textBoxMesFile.Text = MPanel.myModule.MesFilePath;
		}
		if( MPanel.InitDataList == null ) {
			richTextBoxSim.Text = "";
		}
		else {
			richTextBoxSim.Text = MPanel.InitDataList + "\n";
		}
		for( int i = 0; i < MPanel.mySimObjList.Length; ++i ) {
			if( MPanel.mySimObjList[i] != null ) {
				SimulateObj so = MPanel.mySimObjList[i];
				richTextBoxSim.Text += so.X + "," + so.Y + "," + so.Width + "," + so.Height + "," + so.SimType +
					"," + so.Value1 + "," + so.Value2 + "," + so.Value3 + "\n";
			}
		}
		richTextBoxSim.Text = richTextBoxSim.Text.TrimEnd( '\n' );
		
		this.Text = "组件设计器 <" + CurrentModuleFilePath + ">";
	}
	
	//窗体关闭事件
	void ModuleFormClosing(object sender, FormClosingEventArgs e)
	{
		if( NameChanged ) {
			MessageBox.Show( "端口名称已被修改, 但尚未更新到端口!" );
		}
		if( SimValue ) {
			MessageBox.Show( "仿真参数已被修改, 但尚未更新, 请先点击 <设置仿真控件属性> 按钮更新" );
			e.Cancel = true;
			return;
		}
		if( isChanged ) {
			DialogResult d = MessageBox.Show( "文件已经被修改过, 需要保存吗?", "保存提示", MessageBoxButtons.YesNoCancel );
			if( d == DialogResult.Cancel ) {
				e.Cancel = true;
				return;
			}
			if( d == DialogResult.Yes ) {
				保存当前组件buttonClick( null, null );
			}
		}
	}
	
	void 打开图片文件buttonClick(object sender, EventArgs e)
	{
		//打开文件对话框
		OpenFileDialog OpenFileDlg = new OpenFileDialog();
		OpenFileDlg.Filter = "图片文件 | *.*";
		OpenFileDlg.Title = "请选择一个图片文件作为背景";
		DialogResult dlgResult = OpenFileDlg.ShowDialog();
		if(dlgResult == DialogResult.OK) {
			string FilePath = OpenFileDlg.FileName;
			try{
				if( MPanel.myModule == null ) {
					int x = MPanel.Width / 2;
					int y = MPanel.Height / 2;
					MPanel.myModule = new UserModule( 组件名称textBox.Text, x, y );
				}
				Bitmap bm = new Bitmap( FilePath );
				MPanel.myModule.SetBackImage( new Bitmap( bm ) );
				bm.Dispose();
				MPanel.myModule.ImagePath = FilePath;
				textBoxImgPath.Text = MPanel.myModule.ImagePath;
				MPanel.Invalidate();
			}
			catch {
				MessageBox.Show( "不支持此图片格式: " + FilePath );
				return;
			}
		}
	}
	
	void 组件名称textBoxTextChanged(object sender, EventArgs e)
	{
		if( ( (TextBox)sender ).Text != "" && MPanel.myModule != null ) {
			MPanel.myModule.Name = ( (TextBox)sender ).Text;
		}
	}
	
	void 添加端口buttonClick(object sender, EventArgs e)
	{
		if( this.textBox名称.Text == "" ) {
			MessageBox.Show( "请输入端口名称" );
			return;
		}
		string PortName = this.textBox名称.Text;
		string FuncType = this.comboBoxMasOrCli.Text;
		string FuncName = "," + this.comboBox端口功能名称.Text + ",";
		string Dir = this.comboBox导线方向.Text;
		string ExtValue = this.textBoxPortExt.Text;
		
		E_DirType DirType = E_DirType.NONE;
		switch( Dir ) {
			case "UP":		DirType = E_DirType.UP; break;
			case "DOWN":	DirType = E_DirType.DOWN; break;
			case "LEFT":	DirType = E_DirType.LEFT; break;
			case "RIGHT":	DirType = E_DirType.RIGHT; break;
			case "NONE":	DirType = E_DirType.NONE; break;
			default:		MessageBox.Show( "添加端口buttonClick: 未知的端口方向枚举类型: <" + Dir + ">" ); break;
		}
		UserPort port = new UserPort( PortName, FuncType, FuncName, null, null, DirType, ExtValue );
		port.isNew = true;
		string Error = MPanel.myPortList.AddPort( port, true );
		if( Error != null ) {
			MessageBox.Show( "添加端口失败,原因: " + Error );
		}
	}
	
	void 打开组件文件buttonClick(object sender, EventArgs e)
	{
		//打开文件对话框
		OpenFileDialog OpenFileDlg = new OpenFileDialog();
		OpenFileDlg.Filter = "组件文件 *.M | *.M";
		OpenFileDlg.Title = "请选择一个组件文件";
		DialogResult dlgResult = OpenFileDlg.ShowDialog();
		if(dlgResult == DialogResult.OK) {
			try {
				CurrentModuleFilePath = OpenFileDlg.FileName;
				LoadModule( OpenFileDlg.FileName );
			}
			catch {
				MessageBox.Show( "组件导入失败" );
			}
		}
	}
	
	void 导出组件buttonClick(object sender, EventArgs e)
	{
		//保存文件对话框
		SaveFileDialog SaveFileDlg = new SaveFileDialog();
		SaveFileDlg.Filter = "组件 - *.M)|*.M";
		SaveFileDlg.Title = "保存组件到...";
		
		DialogResult dlgResult = SaveFileDlg.ShowDialog();
		if(dlgResult == DialogResult.OK) {
			CurrentModuleFilePath = SaveFileDlg.FileName;
			SaveModule( SaveFileDlg.FileName );
		}
	}
	
	void 保存当前组件buttonClick(object sender, EventArgs e)
	{
		if( CurrentModuleFilePath == null ) {
			MessageBox.Show( "无法保存,因为没有打开一个组件.您可以[导出组件]" );
			return;
		}
		SaveModule( CurrentModuleFilePath );
	}
	
	void SaveModule( string FileName )
	{
		if( MPanel.myModule == null ) {
			MessageBox.Show( "没有目标组件,无法导出" );
			return;
		}
		if( this.组件名称textBox.Text == "" ) {
			MessageBox.Show( "组件名称不能为空" );
			return;
		}
		
		if( textBoxDriverPath.Text != "" ) {
			MPanel.myModule.DriverFilePath = textBoxDriverPath.Text;
			MPanel.myModule.UserName = textBoxUserName.Text;
			MPanel.myModule.DeviceType = textBoxType.Text;
			
			if( MPanel.myModule.UserName.IndexOf( "," ) == -1 ) {
				MPanel.myModule.UserName = "Pack," + MPanel.myModule.UserName;
			}
			MPanel.myModule.ImageList = textBoxImageList.Text;
		}
		if( textBoxConfig.Text != "" ) {
			MPanel.myModule.Config = textBoxConfig.Text;
		}
		else {
			MPanel.myModule.UserName = "";
			MPanel.myModule.DeviceType = "";
			MPanel.myModule.DriverFilePath = "";
		}
		if( textBoxMesFile.Text != "" ) {
			MPanel.myModule.MesFilePath = textBoxMesFile.Text;
		}
		else {
			MPanel.myModule.MesFilePath = null;
		}
		if( textBoxEX.Text != "" ) {
			MPanel.myModule.EXMes = textBoxEX.Text;
		}
		else {
			MPanel.myModule.EXMes = null;
		}
		MPanel.myModule.isControlModule = this.checkBox控制器组件.Checked;
		//MPanel.myModule.isClientModule = this.checkBox控件类组件.Checked;
		//MPanel.myModule.isClientControlPad = this.checkBox客户端控制板.Checked;
		MPanel.myModule.isClientChannel = this.checkBox通信通道.Checked;
		MPanel.myModule.isVHRemoModule = this.checkBoxRemo.Checked;
		MPanel.myModule.isYuanJian = this.checkBoxYuanJian.Checked;
		MPanel.myModule.CanSwap = this.checkBoxCanSwap.Checked;
		MPanel.Save( FileName );
		
		isChanged = false;
	}
	
	void ButtonScaleClick(object sender, EventArgs e)
	{
		if( MPanel.myModule != null ) {
			if( !this.textBoxScale.Text.StartsWith( "*" ) ) {
				MPanel.myModule.ChangeSize( int.Parse( this.textBoxScale.Text ) );
			}
			else {
				
				MPanel.myModule.ChangeSize( float.Parse( this.textBoxScale.Text.Remove( 0, 1 ) ) );
			}
		}
		MPanel.Invalidate();
	}
	
	void ButtonRestoreClick(object sender, EventArgs e)
	{
		if( UserPortList.SelectedPort == null ) {
			MessageBox.Show( "请先选择一个端口" );
			return;
		}
		string PortName = this.textBox名称.Text;
		//string FuncType = this.功能类型comboBox.Text;
		//string FuncName = this.功能名称comboBox.Text;
		string Dir = this.comboBox导线方向.Text;
		string ExtValue = textBoxPortExt.Text;
		E_DirType DirType = E_DirType.NONE;
		switch( Dir ) {
			case "UP":		DirType = E_DirType.UP; break;
			case "DOWN":	DirType = E_DirType.DOWN; break;
			case "LEFT":	DirType = E_DirType.LEFT; break;
			case "RIGHT":	DirType = E_DirType.RIGHT; break;
			case "NONE":	DirType = E_DirType.NONE; break;
			default:		MessageBox.Show( "ButtonRestoreClick: 未知的端口方向枚举类型: " + Dir ); break;
		}
		UserPortList.SelectedPort.Name = PortName;
		UserPortList.SelectedPort.DirType = DirType;
		
		string FuncType = this.comboBoxMasOrCli.Text;
		string FuncName = null;
		FuncName = this.comboBox端口功能名称.Text;
		
		UserPortList.SelectedPort.FuncType = FuncType;
		UserPortList.SelectedPort.FuncName = "," + FuncName + ",";
		UserPortList.SelectedPort.ExtValue = ExtValue;
		
		NameChanged = false;
		
		MPanel.Invalidate();
	}
	
	void ButtonDeleteClick(object sender, EventArgs e)
	{
		if( MessageBox.Show( "确定要删除端口吗?", "删除提示", MessageBoxButtons.YesNo ) == DialogResult.No ) {
			return;
		}
		if( UserPortList.SelectedPort == null ) {
			MessageBox.Show( "请先选择一个端口" );
			return;
		}
		UserPortList.SelectedPort.owner.Delete( UserPortList.SelectedPort );
		MPanel.Invalidate();
	}
	
	//------------------------------------------------------------------
	bool SimValue = false;
	
	//设置仿真控件属性
	void ButtonSetSimValueClick(object sender, EventArgs e)
	{
		SimValue = false;
		
		MPanel.ClearSimList();
		MPanel.SetSimListValue( this.richTextBoxSim.Text );
		MPanel.Invalidate();
	}
	
	void TextBoxScaleDoubleClick(object sender, EventArgs e)
	{
		this.textBoxScale.Text = "0.262144";
	}
	
	void CheckBox254CheckedChanged(object sender, EventArgs e)
	{
		if( checkBox254.Checked ) {
			UserPort.Per = UserPort.Per254;
		}
		else {
			UserPort.Per = UserPort.Per200;
		}
		MPanel.Invalidate();
	}
	
	void RichTextBoxSimTextChanged(object sender, EventArgs e)
	{
		SimValue = true;
	}
	
	int RTick = 0;
	void 保存当前组件buttonMouseDown(object sender, MouseEventArgs e)
	{
		if( e.Button == MouseButtons.Right ) {
			RTick++;
			if( RTick == 3 ) {
				panel1.Width = 472;
			}
		}
	}
	
	
	void ButtonSetNumberClick(object sender, EventArgs e)
	{
		textBoxPortExt.Text = "0*";
	}
	
	void ButtonNoteClick(object sender, EventArgs e)
	{
		textBoxPortExt.Text = "*0";
	}
	
	
	void ButtonA0Click(object sender, EventArgs e)
	{
		textBoxEX.Text = "0";
	}
	
	void ButtonD1Click(object sender, EventArgs e)
	{
		textBoxEX.Text = "1";
	}
	
	void ButtonB2Click(object sender, EventArgs e)
	{
		textBoxEX.Text = "2";
	}
	
	bool NameChanged;
	void TextBox名称Click(object sender, EventArgs e)
	{
		NameChanged = true;
	}
}
}





